package top.huxy.boot.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import top.huxy.boot.exception.RequestAbortedException;
import top.huxy.boot.exception.ZipFailException;
import top.huxy.boot.service.SystemService;
import top.huxy.boot.util.DateUtils;
import top.huxy.boot.util.ExceptionUtils;
import top.huxy.boot.util.ZipUtils;

import java.io.File;
import java.lang.management.ManagementFactory;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class SystemServiceImpl implements SystemService {

    @Autowired
    RedisTemplate<String, Object> redisTemplate;

    @Value("${huxy.app.upload.cms-path}")
    private String cmsPath;
    @Value("${huxy.app.upload.view-path}")
    private String viewPath;

    @Value("${huxy.app.upload.temp-file-path}")
    private String filePathTemp;

    @Value("${huxy.app.upload.zip-password}")
    private String zipPassword;

    @Value("${huxy.app.upload.update-jar-path}")
    private String updateJarPath;

    @Value("${huxy.app.upload.shell-path}")
    private String shellPath;

    @Override
    public void updateView(String token) {
        unZip(token, viewPath);
    }

    @Override
    public void updateCMS(String token) {
        unZip(token, cmsPath);
    }

    @Override
    public void updateSystem(String token) {
        File rawJarFile = unZip(token, updateJarPath).get(0);
        if (rawJarFile == null) {
            throw new RequestAbortedException("上传的压缩包内容为空");
        }

        String now = DateUtils.format("yyyy年MM月dd日HH时mm分ss秒", new Date());

        //生成文件名
        String jarFileName = now + ".jar";
        if (!rawJarFile.renameTo(new File(updateJarPath + jarFileName))) {
            throw new RequestAbortedException("文件移动失败");
        }
        File shellFile = new File(shellPath);
        if (shellFile.isFile()) {
            //创建shell脚本
            String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
            int duration = 3000;
            StringBuilder shellCommand = new StringBuilder();
            shellCommand.append("sh ")
                    .append(shellPath)
                    .append(" ")
                    .append(pid)
                    .append(" ").append(updateJarPath).append(jarFileName)
                    .append(" ").append(updateJarPath).append("logs/").append(now).append(".log");

            new Thread(() -> {
                try {
                    Thread.sleep(duration);
                    Runtime.getRuntime().exec(shellCommand.toString()).waitFor();
                } catch (Throwable th) {
                    log.error("error", th);
                    ExceptionUtils.logError(th);
                }
            }).start();
        } else {
            throw new RequestAbortedException("没有找到shell文件");
        }
    }

    private List<File> unZip(String uploadFileName, String distPath) {
        Boolean hasKey = redisTemplate.hasKey(uploadFileName);
        if (hasKey != null && hasKey) {
            File file = new File(filePathTemp + uploadFileName);
            if (file.isFile()) {
                try {
                    return ZipUtils.unZip(file, distPath, zipPassword);
                } catch (ZipFailException e) {
                    throw new RequestAbortedException(e.getMessage());
                } catch (Exception e) {
                    ExceptionUtils.logError(e);
                    throw new RequestAbortedException("文件解压失败,请查看日志");
                }
            } else {
                throw new RequestAbortedException("没找到文件");
            }
        } else {
            throw new RequestAbortedException("token不存在或已过期");
        }
    }
}
